package com.icexxx.litchi;

import java.net.ConnectException;
import java.util.Properties;

import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.core.env.Environment;

public class Litchi {
    private static Litchi litchi = null;
    private boolean showMessage;
    private Integer port;
    private boolean isWindows;

    private Litchi() {

    }

    public static Litchi create(Environment environment, ServerProperties serverProperties) {
        if (litchi == null) {
            litchi = new Litchi(environment, serverProperties);
        }
        return litchi;
    }

    private Litchi(Environment environment, ServerProperties serverProperties) {
        init(environment, serverProperties);
    }

    private void init(Environment environment, ServerProperties serverProperties) {
        String osName = osName();
        boolean isWindows = isWindows(osName);
        Integer port = getPort(serverProperties);
        boolean showLitchi = false;
        if (environment != null) {
            String[] activeProfiles = environment.getActiveProfiles();
            showLitchi = showLitchi(activeProfiles, isWindows);
        }
        boolean isMac = false;
        // 判断是否为苹果系统
        isMac = isMac(osName);
        showMessage = showLitchi && !isMac;
        this.port = port;
        this.isWindows = isWindows;
    }

    public void shutdownPort() {
        if (showMessage) {
            shutdown(port, isWindows);
        }
    }

    private boolean isMac(String osName) {
        if (osName == null || "".equals(osName)) {
            return false;
        }
        String lowerCaseOsName = osName.toLowerCase();
        if (lowerCaseOsName.startsWith("mac os")) {
            return true;
        }
        return false;
    }

    private void shutdown(Integer port, boolean isWindows) {
        try {
            doShutdown(port, isWindows);
        } catch (Exception e) {
            if (e instanceof ConnectException) {
                // NOP
            }
            e.printStackTrace();
        }
    }

    private void doShutdown(Integer port, boolean isWindows) {
        if (isWindows) {
            windowsShutdown(port);
        } else {
            linuxShutdown(port);
        }
    }

    private void linuxShutdown(Integer port) {
        LinuxPortUtil.close(port);
    }

    private void windowsShutdown(Integer port) {
        LitchiPortUtil.close(port);
    }

    private Integer getPort(ServerProperties serverProperties) {
        Integer port = 8080;
        if (serverProperties != null) {
            Integer portActual = serverProperties.getPort();
            if (portActual != null && portActual.intValue() != 0) {
                port = portActual;
            }
        }
        return port;
    }

    private static boolean showLitchi(String[] activeProfiles, boolean isWindows) {
        if (activeProfiles == null) {
            return true;
        }
        if (activeProfiles.length == 0) {
            return isWindows;
        }
        String defaultValue = activeProfiles[0];
        if ("prod".equalsIgnoreCase(defaultValue) || "uat".equalsIgnoreCase(defaultValue)
                || "product".equalsIgnoreCase(defaultValue)) {
            return false;
        }
        if ("dev".equalsIgnoreCase(defaultValue) || "test".equalsIgnoreCase(defaultValue)
                || "develop".equalsIgnoreCase(defaultValue)) {
            return true;
        }
        return false;
    }

    public static String osName() {
        Properties properties = System.getProperties();
        String value = (String) properties.get("os.name");
        return value;
    }

    public static boolean isWindows(String osName) {
        if (osName != null && osName.toLowerCase().contains("windows")) {
            return true;
        }
        return false;
    }

    public static boolean isWindows() {
        String osName = osName();
        if (osName != null && osName.toLowerCase().contains("windows")) {
            return true;
        }
        return false;
    }
}
